/**************************************************************************
 * Copyright (C) 2019-2019  Unisound
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 **************************************************************************
 *
 * Description : ac_device_simulator.c
 * Author      : liuwenzheng@unisound.com
 * Date        : 2019.12.30
 *
 **************************************************************************/

#include "ac_device_simulator.h"
#include "uni_log.h"

#define TAG  "ac_device"

typedef struct {
  eAcSate       state;
  eAcWindSpeed  speed;
  eAcMode       mode;
  eAcTemp       temp;
  eAcSwing      swing;
  uni_bool      is_sleep_on;
  uni_bool      is_humid_on;
  uni_bool      is_screen_on;
  uni_bool      is_energy_on;
}eAcContext_t;

static eAcContext_t g_ac_context = {0};

eAcSate AcDeviceGetState(void) {
  return g_ac_context.state;
}

eAcSate AcDeviceSetState(eAcSate state) {
  if ((state > eACSTATE_UNKONWN) && (state < eACSTATE_MAX)) {
    g_ac_context.state = state;
  }
  return g_ac_context.state;
}

eAcWindSpeed AcDeviceGetWindSpeed(void) {
  return g_ac_context.speed;
}

eAcWindSpeed AcDeviceSetWindSpeed(eAcWindSpeed speed) {
  if (eACMODE_DRY == g_ac_context.mode) {
    return g_ac_context.speed;
  }
  if ((speed > eACWINDSPEED_UNKONWN) && (speed < eACWINDSPEED_MAX)) {
    g_ac_context.speed = speed;
  }
  return g_ac_context.speed;
}

eAcWindSpeed AcDeviceWindSpeedInc(void) {
  if (eACWINDSPEED_UNKONWN == g_ac_context.speed) {
    g_ac_context.speed = eACWINDSPEED_LOW;
  } else if (g_ac_context.speed < eACWINDSPEED_HIGH) {
    g_ac_context.speed += 1;
  }
  return g_ac_context.speed;
}

eAcWindSpeed AcDeviceWindSpeedDec(void) {
  if (eACWINDSPEED_UNKONWN == g_ac_context.speed) {
    g_ac_context.speed = eACWINDSPEED_HIGH;
  } else if (g_ac_context.speed > eACWINDSPEED_LOW) {
    g_ac_context.speed -= 1;
  }
  return g_ac_context.speed;
}

eAcMode AcDeviceGetMode(void) {
  return g_ac_context.mode;
}

eAcMode AcDeviceSetMode(eAcMode mode) {
  if ((mode > eACMODE_UNKONWN) && (mode < eACMODE_MAX)) {
    g_ac_context.mode = mode;
  }
  return g_ac_context.mode;
}

eAcTemp AcDeviceGetTemp(void) {
  return g_ac_context.temp;
}

eAcTemp AcDeviceSetTemp(eAcTemp temp) {
  if ((temp > eACTEMP_UNKONWN) && (temp < eACTEMP_MAX)) {
    g_ac_context.temp = temp;
  }
  return g_ac_context.temp;
}

eAcTemp AcDeviceTempInc(void) {
  if (eACTEMP_UNKONWN == g_ac_context.temp) {
    g_ac_context.temp = eACTEMP_16;
  } else if (g_ac_context.temp < eACTEMP_32) {
    g_ac_context.temp += 1;
  }
  return g_ac_context.temp;
}

eAcTemp AcDeviceTempDec(void) {
  if (eACTEMP_UNKONWN == g_ac_context.temp) {
    g_ac_context.temp = eACTEMP_32;
  } else if (g_ac_context.temp > eACTEMP_16) {
    g_ac_context.temp -= 1;
  }
  return g_ac_context.temp;
}

eAcTemp AcDeviceTempIncBig(void) {
  if (eACTEMP_UNKONWN == g_ac_context.temp) {
    g_ac_context.temp = eACTEMP_16;
  } else if (g_ac_context.temp <= (eACTEMP_32 - 3)) {
    g_ac_context.temp += 3;
  } else {
    g_ac_context.temp = eACTEMP_32;
  }
  return g_ac_context.temp;
}

eAcTemp AcDeviceTempDecBig(void) {
  if (eACTEMP_UNKONWN == g_ac_context.temp) {
    g_ac_context.temp = eACTEMP_32;
  } else if (g_ac_context.temp >= (eACTEMP_16 + 3)) {
    g_ac_context.temp -= 3;
  } else {
    g_ac_context.temp = eACTEMP_16;
  }
  return g_ac_context.temp;
}

eAcSwing AcDeviceGetSwingState(void) {
  return g_ac_context.swing;
}

eAcSwing AcDeviceSetSwingState(eAcSwing swing) {
  switch (swing) {
    case eACSWING_CROSS_ON:
      if (eACSWING_VERT_ON == g_ac_context.swing
        || eACSWING_ALL_ON == g_ac_context.swing) {
        g_ac_context.swing = eACSWING_ALL_ON;
      }
      g_ac_context.swing = eACSWING_CROSS_ON;
      break;
    case eACSWING_CROSS_OFF:
      if (eACSWING_VERT_OFF == g_ac_context.swing
        || eACSWING_ALL_OFF == g_ac_context.swing) {
        g_ac_context.swing = eACSWING_ALL_OFF;
      }
      g_ac_context.swing = eACSWING_CROSS_OFF;
      break;
    case eACSWING_VERT_ON:
      if (eACSWING_CROSS_ON == g_ac_context.swing
        || eACSWING_ALL_ON == g_ac_context.swing) {
        g_ac_context.swing = eACSWING_ALL_ON;
      }
      g_ac_context.swing = eACSWING_VERT_ON;
      break;
    case eACSWING_VERT_OFF:
      if (eACSWING_CROSS_OFF == g_ac_context.swing
        || eACSWING_ALL_OFF == g_ac_context.swing) {
        g_ac_context.swing = eACSWING_ALL_OFF;
      }
      g_ac_context.swing = eACSWING_VERT_OFF;
      break;
    case eACSWING_ALL_ON:
      g_ac_context.swing = eACSWING_ALL_ON;
      break;
    case eACSWING_ALL_OFF:
      g_ac_context.swing = eACSWING_ALL_OFF;
      break;
    default:
      break;
  }
  return g_ac_context.swing;
}

uni_bool AcDeviceGetSkillState(eAcSkill skill) {
  uni_bool is_on = false;
  switch (skill) {
    case eACSKILL_SLEEP:
      is_on = g_ac_context.is_sleep_on;
      break;
    case eACSKILL_HUMID:
      is_on = g_ac_context.is_humid_on;
      break;
    case eACSKILL_SCREEN:
      is_on = g_ac_context.is_screen_on;
      break;
    case eACSKILL_ENERGY:
      is_on = g_ac_context.is_energy_on;
      break;
    default:
      is_on = false;
      break;
  }
  return is_on;
}

uni_bool AcDeviceSetSkillState(eAcSkill skill, uni_bool is_on) {
  uni_bool ret = false;
  switch (skill) {
    case eACSKILL_SLEEP:
      ret = g_ac_context.is_sleep_on = is_on;
      break;
    case eACSKILL_HUMID:
      ret = g_ac_context.is_humid_on = is_on;
      break;
    case eACSKILL_SCREEN:
      ret = g_ac_context.is_screen_on = is_on;
      break;
    case eACSKILL_ENERGY:
      ret = g_ac_context.is_energy_on = is_on;
      break;
    default:
      ret = false;
      break;
  }
  return ret;
}

int AcDeviceInit(void) {
  g_ac_context.mode = eACMODE_COOL;
  g_ac_context.swing = eACSWING_ALL_OFF;
  g_ac_context.speed = eACWINDSPEED_LOW;
  g_ac_context.state = eACSTATE_OFF;
  g_ac_context.temp = eACTEMP_16;
  g_ac_context.is_energy_on = false;
  g_ac_context.is_humid_on = false;
  g_ac_context.is_screen_on = false;
  g_ac_context.is_sleep_on = false;
  return 0;
}

void AcDeviceFinal(void) {
  uni_memset(&g_ac_context, 0, sizeof(g_ac_context));
}

